/**
 *
 */
package com.ebocy.hammer.world.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;

import org.apache.log4j.Logger;

import com.ebocy.hammer.core.GameCache;
import com.ebocy.hammer.core.constants.GameConstants;
import com.ebocy.hammer.core.domain.GamePlayer;
import com.ebocy.hammer.core.domain.Room;
import com.ebocy.hammer.core.log.EbocyLogManager;
import com.ebocy.hammer.core.message.AbstractS2CMessage;
import com.ebocy.hammer.core.util.ServerAddress;
import com.ebocy.hammer.world.message.RoomPlayerInfo;
import com.ebocy.hammer.world.message.S2CJoin4V4RoomMessage;
import com.ebocy.hammer.world.message.S2CRoomFullMessage;
import com.ebocy.hammer.world.message.S2CRoomMemberUpdateMessage;
import com.ebocy.hammer.world.resourceManage.ConnectionCount;

/**
 * @author Qingrong Hou
 * 
 *         May 24, 2012
 */
public class TeamService {
	protected static Logger logger = EbocyLogManager.getSystemLogger();
	private static TeamService teamService = new TeamService();

	public static TeamService getInstance() {
		return teamService;
	}

	private Random random = new Random();

	/**
	 * 进入排队队列<br>
	 * 1.如果是战斗退出后重新组队，将房间人员重新组合，并添加新人开战 2.如果第一次进入战斗，进入已有队列或者创建队列
	 */
	public synchronized void enter4V4FightQueue(GamePlayer gamePlayer, int roomId) {
		if (roomId == 0) {
			join4V4FightQueue(gamePlayer);
		} else {
			Room room = GameCache.getRoom(roomId);
			if (room == null)
				room = creatRoom(roomId);
			room.addWorld(gamePlayer.getGamePlayerId(),gamePlayer);
		}
	}

	/**
	 * 进入排队列表<br>
	 * 1.如果队列为空，创建空队列，玩家加入<br>
	 * 2.如果队列已有人，且未满足8人，玩家加入<br>
	 * 3.如果队列人数已满，满员队列进入排队结束流程；此玩家创建新队列，并加入
	 */
	private synchronized void join4V4FightQueue(GamePlayer gamePlayer) {
		logger.info("玩家    " + gamePlayer.getName() + "    开始排队");
		// 排队列表
		List<Room> outGoingRoomList = new ArrayList<Room>();
		Room room = null;
		if (GameCache.queueLen() == 0) { // 队列中无房间，创建房间
			room = creatRoom(0);
			gamePlayer.setRoomId(room.roomId);
			// 玩家 加入房间
			room.addWorld(gamePlayer.getGamePlayerId(), gamePlayer);
			logger.info("    玩家    " + gamePlayer.getName() + "  创建了一个新房间，房间ID为：" + room.roomId);
		} else {
			int roomId = GameCache.getQueue(); // 队列中有房间，取第一个房间
			room = GameCache.getRoom(roomId);
			if (room.worlds.contains(gamePlayer.getRoomId())) { // 玩家已经在房间中
				logger.info("    玩家    " + gamePlayer.getName() + "  已在一个房间内，ID为：" + room.roomId + "此哥们是否反复在排队？？");
				return;
			}
			if (room.worlds.size() < GameCache.getTeamMember()) {
				gamePlayer.setRoomId(room.roomId);
				// 玩家 加入房间
				room.addWorld(gamePlayer.getGamePlayerId(), gamePlayer);
			} else {
				outGoingRoomList.add(room);
				// 当前玩家继续排队
				join4V4FightQueue(gamePlayer);
			}

			if (room.worlds.size() == GameCache.getTeamMember()) // 当前房间已满
				outGoingRoomList.add(room);

			// 通知房间中其他玩家有人加入
			AbstractS2CMessage memberUpdateMessage = new S2CRoomMemberUpdateMessage(gamePlayer, S2CRoomMemberUpdateMessage.INCREASE);
			gamePlayer.sendMessageToRoomOther(memberUpdateMessage);
		}

		// 返回队伍中玩家信息
		List<RoomPlayerInfo> memberInfoList = new ArrayList<RoomPlayerInfo>();
		for (Long member : room.worlds) {
			if (gamePlayer.getGamePlayerId() != member) {
				GamePlayer gpl = GameCache.getInstance().getCache(member);
				RoomPlayerInfo playerInfo = new RoomPlayerInfo(gpl.getGamePlayerId(), gpl.getName(), gpl.getHeadPortrait(), gpl.getRoleImage(), gpl.getHammerId(), null);
				memberInfoList.add(playerInfo);
			}
			
		}
		AbstractS2CMessage memberInfoMessage = new S2CJoin4V4RoomMessage(memberInfoList);
		gamePlayer.sendMessage(memberInfoMessage);

		// 如果队列中有房间已满，通知房间内玩家
		if (outGoingRoomList.size() > 0) {
			for (Room outGoingRoom : outGoingRoomList)
				roomFull(outGoingRoom);
		}
	}

	/**
	 * 房间人数已满，发消息通知玩家
	 */
	private void roomFull(Room outGoingRoom) {
		//满员房间,加锁
		outGoingRoom.saveRoome(3);
		
		// 满员房间出队
		GameCache.delQueue();
		logger.info("房间号为" + outGoingRoom.roomId + "的房间人数已满，从排队列表中移除");

		// 随机一张地图
		String[] mapNameArray = GameCache.blockMap.keySet().toArray(new String[0]);
		String mapName = mapNameArray[random.nextInt(mapNameArray.length)]; // 随机一张地图
		logger.info("房间ID为：" + outGoingRoom.roomId + "的一组玩家进入的地图名字：" + mapName);

		// 通知每个玩家换服
		for (Long number : outGoingRoom.worlds) {
			GamePlayer gamePlayer =GameCache.getInstance().getCache(number);
			// 给玩家返回一个唯一的房间ID，供在Battle服务器重新会合
			ServerAddress serverAddress = ConnectionCount.getBattleServerAddress();
			AbstractS2CMessage roomFullMessage = new S2CRoomFullMessage(serverAddress.getIp(), serverAddress.getPort(), outGoingRoom.roomId, mapName);
			gamePlayer.sendMessage(roomFullMessage);
		}
	}

	/**
	 * 将玩家放入到一个新队列中192.168.16.78:8388
	 */
	private Room creatRoom(int roomId) {
		Room room= new Room();
		if (roomId == 0)
			roomId = GameCache.getIncr();
		room.roomId = roomId;
		room.worlds = new HashSet<Long>();
		GameCache.addQueue(room.roomId); // insert element

		return room;
	}

	/**
	 * 取消排队
	 */
	public void quit4V4Queue(GamePlayer gamePlayer) {
		// 从排队列表中删除此玩家
		Room room = GameCache.getRoom(gamePlayer.getRoomId());
		room.delWorld(gamePlayer.getGamePlayerId());
		// 通知其他队伍中的玩家
		AbstractS2CMessage memberUpdateMessage = new S2CRoomMemberUpdateMessage(gamePlayer, S2CRoomMemberUpdateMessage.DECREASE);
		gamePlayer.sendMessageToRoomOther(memberUpdateMessage);
	}
}
